<?php

class sfCaptcha
{
  // security string displayed on CAPTCHA image (string)
  public $securityCode;
  // security string length (string)
  private $codeLength;
  // list of characters for use in the security string displayed on CAPTCHA image (string)
  private $characterList;
  // image used as a template for CAPTCHA image (string)
  private $imageFile;
  // minimum font size for text displayed on image (integer)
  public $fontSize;           
  // allowed colors for use on the CAPTCHA image (array) of (string)s
  public $colors;
  // font names to be used in CAPTCHA image (array) of (string)s
  public $fonts;
  
  public function __construct()
  {
    // retrieve setting from app.yml
    $params = sfConfig::get('app_captcha_param');
    
    $this->codeLength = $params['length'];
    $this->imageFile = $params['image'];
    $this->characterList = mb_strtoupper($params['characters']);
    $this->fontSize = $params['size'];
    $this->colors = $params['colors'];
    $this->fonts = $params['fonts'];
    
  }
  
 /*
 // generates random security string of specified length out of provided character list
 // returns $newstring (string)
 */  
  public function simpleRandString() 
  {	  
    mt_srand((double)microtime()*1000000);
 
    $newstring = "";
 
    if ($this->codeLength > 0) {
        while (strlen($newstring) < $this->codeLength) {
            $newstring .= $this->characterList[mt_rand(0, strlen($this->characterList)-1)];
        }
    }
    return $newstring;
  }
  
 /*
 // generates CAPTCHA image of the string generated by simpleRandString()
 */
  public function generateImage()
  {
 
    $this->securityCode = $this->simpleRandString();
 
    $img_path = SF_ROOT_DIR.DIRECTORY_SEPARATOR.'web'.DIRECTORY_SEPARATOR.'uploads'.DIRECTORY_SEPARATOR.'assets'.DIRECTORY_SEPARATOR;
 
    if(!is_writable($img_path) && !is_dir($img_path)){
      $error = "The image path $img_path does not appear to be writable or the folder does not exist. Please verify your settings";
      throw new Exception($error);
    }
    
    $this->img = ImageCreateFromJpeg($img_path.$this->imageFile) or die();
 
    $img_size = getimagesize($img_path.$this->imageFile);
 
    foreach($this->colors as $fcolor)
    {
        $color[] = $this->hexColorAllocate($fcolor);
    }
    
    $c = rand(0, (count($color)-1));
    $line = $this->hexColorAllocate($this->colors[$c]);
    
    $c = rand(0, (count($color)-1));
    $line2 = $this->hexColorAllocate($this->colors[$c]);
 
    $fw = imagefontwidth($this->fontSize)+3;
    $fh = imagefontheight($this->fontSize);
 
    // create a new string with a blank space between each letter so it looks better
    $newstr = "";
    for ($i = 0; $i < strlen($this->securityCode); $i++) {
        $newstr .= $this->securityCode[$i] ." ";
    }
 
    // remove the trailing blank
    $newstr = trim($newstr);
 
    // center the string 
    $x = ($img_size[0] - strlen($newstr) * $fw ) / 2;
 
    foreach( $this->fonts as $fontName){
      $font[] = SF_ROOT_DIR.DIRECTORY_SEPARATOR.'web'.DIRECTORY_SEPARATOR.'uploads'.DIRECTORY_SEPARATOR.'assets'.DIRECTORY_SEPARATOR.$fontName.'.ttf';
    }
 
    // create random lines over text
    for($i=0; $i <3;$i++){
        $s_x = rand(40,180);
        $s_y = rand(5,35);
        $e_x = rand(($s_x-50), ($s_x+50));
        $e_y = rand(5,35);
        $c = rand(0, (count($color)-1));
      imageline($this->img, $s_x,$s_y, $e_x,$e_y, $color[$c]);
    }
 
    // random bg ellipses
    imageellipse($this->img, $s_x, $s_y, $e_x, $e_y, $line);
    imageellipse($this->img, $e_x, $e_y, $s_x, $s_y, $line2);
 
    // output each character at a random height and standard horizontal spacing
    for ($i = 0; $i < strlen($newstr); $i++) {
        $hz = mt_rand( 10, $img_size[1] - $fh - 5);
 
        // randomize rotation
        $rotate = rand(-35, 35);
 
        // randomize font size
        $this->fontSize =  rand($fh, $fh+4);
 
        // radomize color
        $c = rand(0, (count($color)-1));
	
	//randomize font
	$f = rand(0, (count($font)-1));
 
        // imagechar( $this->img, $this->fontSize, $x + ($fw*$i), $hz, $newstr[$i], $color);
        //imagettftext($this->img, $this->fontSize,$rotate , $x + ($fw*$i), $hz + 12, $color[0], $font[$c], $newstr[$i]);
	imagettftext($this->img, $this->fontSize,$rotate , $x + ($fw*$i), $hz + 12, $color[$c], $font[$f], $newstr[$i]);
    }
  }
  
  public function hexColorAllocate($hex)
  {
    sscanf($hex, "%2x%2x%2x", $red, $green, $blue);
    return imagecolorallocate($this->img, $red, $green, $blue);
  }
}
